﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using RuneLog.Stats;
using RuneLog.Extensions;
using Ionic.Zip;
namespace RuneLog.AdventerersLog
{
    public partial class AdvlogLookupForm : Form
    {
        public static string GetBodyURL(string rsn)
        {
            return "http://services.runescape.com/m=avatar-rs/" + rsn + "/full.png";
        }
        public static string GetFaceURL(string rsn)
        {
            return "http://services.runescape.com/m=avatar-rs/" + rsn + "/chat.png";
        }
        public static string GetClanBannerURL(string rsn)
        {
            return "http://services.runescape.com/m=avatar-rs/" + rsn + "/ownclan.png";
        }
        private Boolean init = false;
        private static ImageList imgList;
        static AdvlogLookupForm()
        {
            imgList = RunescapeImageList.AsImageList;
        }
        private static Regex skillXPRegex = new Regex("\\d+XP in (\\w+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        private static Regex skillLvlRegex = new Regex("Levelled up (\\w+)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        private static Regex dropRegex = new Regex("I found (?:an?|the)? ?(.+?)\\.?$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        private static Regex killRegex = new Regex("I killed (?:\\d+| ?the)? ([a-z' ]+?)(?:e?s)?\\.?$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        private static Regex levelAllRegex = new Regex("Levelled all skills over (\\d+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        private static Regex capeRegex = new Regex("Bought my first (\\w+)\\.?$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        public AdvlogLookupForm()
        {
            InitializeComponent();
            dataView.SmallImageList = imgList;
            dataView.Columns[0].Width = 75;
            dataView.Columns[1].Width = dataView.Width-80;
            init = true;

            using (ZipFile zip = ZipFile.Read("resources/skills.zip"))
            {
                userImage.Image = Image.FromStream(zip["chat head.png"].OpenReader());
                clanImage.Image = Image.FromStream(zip["default banner.png"].OpenReader());
            }

        }

        private bool isLoaded(PictureBox p)
        {
            return (!p.WaitOnLoad && p.Image != null);
        }


        private void usernameBox_KeyPress(object sender, KeyPressEventArgs e)
        {
        }

        private void updateAdventurersLog()
        {
            List<Entry> log = null;
            try
            {

                log = AdventurersLog.GetLogList(usernameBox.Text.Trim());
            }
            catch (UsernameIsNotMemberException)
            {
                MessageBox.Show(usernameBox.Text.Trim() + " is either not a member, doesn't exist, or has their adventurer's log set to private or friend's only.");
                return;
            }
            var rsn = usernameBox.Text.Trim();

            usernameBox.Clear();
            dataView.Items.Clear();
            List<ListViewItem> items = new List<ListViewItem>();
            foreach (Entry i in log)
            {
                ListViewItem item = new ListViewItem();
                item.Text = i.Date.ToString("MM/dd/yy");
                ListViewItem.ListViewSubItem txt = new ListViewItem.ListViewSubItem()
                {
                    Text = i.Title
                };
                item.SubItems.Add(txt);
                Match m = skillXPRegex.Match(i.Title);
                item.ImageIndex = 0;
                if (m.Success)
                {
                    var sk = (from Capture iv in m.Groups
                              where !String.IsNullOrWhiteSpace(iv.Value) && !iv.Value.Contains(' ')
                              select iv.Value).First(iv => true);

                    if (sk != null)
                        item.ImageIndex = RunescapeImageList.GetID(sk);
                }
                else if ((m = skillLvlRegex.Match(i.Title)).Success)
                {
                    var sk = (from Capture iv in m.Groups
                              where !String.IsNullOrWhiteSpace(iv.Value) && !iv.Value.Contains(' ')
                              select iv.Value).First(iv => true);
                    if (sk != null)
                        item.ImageIndex = RunescapeImageList.GetID(sk);
                    txt.Text = i.Description;
                }
                else if ((m = dropRegex.Match(i.Title)).Success)
                {
                    var drop = m.Groups[1].Value;
                    if (RunescapeImageList.GetID(drop) > -1)
                        item.ImageIndex = RunescapeImageList.GetID(drop);
                    else
                        item.ImageIndex = RunescapeImageList.GetID("drop");
                    txt.Text = i.Description;
                }
                else if ((m = killRegex.Match(i.Title)).Success)
                {
                    var kill = m.Groups[1].Value;
                    if (RunescapeImageList.GetID(kill) > -1)
                        item.ImageIndex = RunescapeImageList.GetID(kill);
                    else
                        item.ImageIndex = RunescapeImageList.GetID("default kill");
                }
                else if ((m = levelAllRegex.Match(i.Title)).Success)
                    item.ImageIndex = RunescapeImageList.GetID("skillbar");
                else if ((m = capeRegex.Match(i.Title)).Success)
                    item.ImageIndex = RunescapeImageList.GetID(m.Groups[1].Value);
                else if (i.Title.ToLower().Contains("quest"))
                    item.ImageIndex = RunescapeImageList.GetID("quest");
                else if (i.Title.ToLower().Contains("daemonheim") || i.Title.ToLower().Contains("dungeon floor"))
                    item.ImageIndex = RunescapeImageList.GetID("Dungeoneering");
                else if (i.Title.ToLower().Contains("treasure trail"))
                    item.ImageIndex = RunescapeImageList.GetID("clue");
                else if (i.Title.ToLower().Contains("ascension crossbow"))
                    item.ImageIndex = RunescapeImageList.GetID("assbow");
                else if (i.Title.ToLower().Contains("i defeated the queen black dragon"))
                    item.ImageIndex = RunescapeImageList.GetID("Queen Black Dragon");
                else if (i.Title.ToLower().Contains("won a case involving"))
                    item.ImageIndex = RunescapeImageList.GetID("court");
                txt.Text = txt.Text.Replace("  ", " ");
                items.Add(item);
            }

            AsyncCompletedEventHandler onLoad = null;
            onLoad = new AsyncCompletedEventHandler((obj, args) =>
            {
                if (!isLoaded(clanImage) || !isLoaded(userImage) || !isLoaded(bodyImage))
                    return;
                clanImage.LoadCompleted -= onLoad;
                userImage.LoadCompleted -= onLoad;
                bodyImage.LoadCompleted -= onLoad;

                clanImage.Visible = userImage.Visible = bodyImage.Visible = true;

                foreach (var iv in items)
                    dataView.Items.Add(iv);

                Text = "Adventurer's Log - " + rsn;

                rsnLabel.Text = rsn;
            });

            clanImage.Visible = userImage.Visible = bodyImage.Visible = false;
            Text = "Adventurer's Log";
            rsnLabel.Text = "";
            clanImage.LoadCompleted += onLoad;
            userImage.LoadCompleted += onLoad;
            bodyImage.LoadCompleted += onLoad;

            if (clanImage.WaitOnLoad)
                clanImage.CancelAsync();
            clanImage.LoadAsync(GetClanBannerURL(rsn));

            if (userImage.WaitOnLoad)
                userImage.CancelAsync();
            userImage.LoadAsync(GetFaceURL(rsn));

            if (bodyImage.WaitOnLoad)
                bodyImage.CancelAsync();
            bodyImage.LoadAsync(GetBodyURL(rsn));
        }

        private void button1_Click(object sender, EventArgs e)
        {
            updateAdventurersLog();
        }

        private void lookupOutputBox_TextChanged(object sender, EventArgs e)
        {

        }

        private void dataView_ColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e)
        {
            if (init)
            {
                e.NewWidth = dataView.Columns[e.ColumnIndex].Width;
                e.Cancel = true;
            }
        }

        private void dataView_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                dataViewMenu.Show(Cursor.Position);
            } 
        }

        private void copyTextToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (dataView.SelectedItems.Count == 0)
                return;
            Point client = PointToClient(MousePosition);
            string date = dataView.SelectedItems[0].SubItems[0].Text;
            string text = dataView.SelectedItems[0].SubItems[1].Text;
            Clipboard.SetText(String.Format("({0}) {1}: {2}", date, rsnLabel.Text, text));
        }
    }
}
